package me.leon.ext.android

import androidx.fragment.app.Fragment
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

inline fun <T> Fragment.extra(default: T, key: String = "") = ExtraFragmentData(this, key, default)

inline fun <reified T> Fragment.extraArray(default: Array<T> = arrayOf(), key: String = "") =
    ExtraFragmentData(this, key, default)

inline fun <T> Fragment.extraList(default: ArrayList<T> = arrayListOf(), key: String = "") =
    ExtraFragmentData(this, key, default)

@Suppress("IMPLICIT_CAST_TO_ANY")
class ExtraFragmentData<T>(
    private val frag: Fragment,
    private val key: String,
    private val default: T
) : ReadOnlyProperty<Any?, T> {

    override fun getValue(thisRef: Any?, property: KProperty<*>): T {

        return getExtra(findProperName(property))
    }

    private fun findProperName(property: KProperty<*>) = key.ifEmpty { property.name }

    private fun getExtra(key: String): T =
        try {
            (frag.arguments?.get(key) as T) ?: default
        } catch (ignored: Exception) {
            throw IllegalArgumentException("Unsupported type.")
        }
}
